﻿using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace CNative.Dapper.Utils
{
    #region IUpdateSqlBuilder
    public partial interface IUpdateSqlBuilder: IExecuteSql
    {
        /// <summary>
        /// 更新一条数据,自动对比新老实体对象属性差异来决定更新字段
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="newEntity">新实体</param>
        /// <param name="oldEntity">老实体</param>
        /// <returns></returns>
        bool Update<TClass>(TClass newEntity, TClass oldEntity) where TClass : class, new();

        /// <summary>
        /// 更新一条数据,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entity">实体对象</param>
        /// <param name="columns">需要更新的字段</param>
        bool Update<TClass>(TClass entity, params string[] columns) where TClass : class, new();

        /// <summary>
        /// 更新多条数据,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entities">数据列表</param>
        /// <param name="isForSet">控制fields</param>
        /// <param name="columns">需要更新的字段</param>
        bool Update<TClass>(List<TClass> entities, params string[] columns) where TClass : class, new();

        /// <summary>
        /// 更新多条数据,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entities">数据列表</param>
        /// <param name="IgnoreColumns">不需要更新的字段</param>
        bool Update<TClass>(List<TClass> entities, IEnumerable<string> IgnoreColumns = null) where TClass : class, new();

        /// <summary>
        /// 更新一条数据,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entity">实体对象</param>
        /// <param name="IgnoreColumns">不需要更新的字段</param>
        bool Update<TClass>(TClass entity, IEnumerable<string> IgnoreColumns = null) where TClass : class, new();
        //---------------------------------------------------------------------------------------------------------------
        /// <summary>
        /// 更新一条数据,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entity">实体对象</param>
        /// <param name="where">条件表达式</param>
        /// <param name="columns">需要更新的字段</param>
        bool Update<TClass>(TClass entity, Expression<Func<TClass, bool>> where, params string[] columns) where TClass : class, new();

        /// <summary>
        /// 更新多条数据,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entities">数据列表</param>
        /// <param name="where">条件表达式</param>
        /// <param name="columns">需要更新的字段</param>
        bool Update<TClass>(List<TClass> entities, Expression<Func<TClass, bool>> where, params string[] columns) where TClass : class, new();

        /// <summary>
        /// 更新多条数据,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entities">数据列表</param>
        /// <param name="where">条件表达式</param>
        /// <param name="IgnoreColumns">不需要更新的字段</param>
        bool Update<TClass>(List<TClass> entities, Expression<Func<TClass, bool>> where, IEnumerable<string> IgnoreColumns = null) where TClass : class, new();

        /// <summary>
        /// 更新一条数据,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entity">实体对象</param>
        /// <param name="where">条件表达式</param>
        /// <param name="IgnoreColumns">不需要更新的字段</param>
        bool Update<TClass>(TClass entity, Expression<Func<TClass, bool>> where, IEnumerable<string> IgnoreColumns) where TClass : class, new();

        /// <summary>
        /// 更新一条数据
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="fields">设置多个更新字段</param>
        /// <param name="where">条件表达式</param>
        /// <returns></returns>
        bool Update<TClass>(Expression<Func<TClass, TClass>> fields, Expression<Func<TClass, bool>> where) where TClass : class, new();

        /// <summary>
        /// 设置多个更新字段
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="field">需要更新的字段</param>
        /// <returns></returns>
        IUpdateSqlBuilder Set<TClass>(Expression<Func<TClass, TClass>> fields) where TClass : class, new();
        /// <summary>
        /// 设置单个更新字段值
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <typeparam name="TField"></typeparam>
        /// <param name="field">更新字段</param>
        /// <param name="value">字段值</param>
        /// <returns></returns>
        IUpdateSqlBuilder Set<TClass, TValue>(Expression<Func<TClass, TValue>> field, TValue value) where TClass : class, new();

        /// <summary>
        /// 添加条件表达式
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="where"></param>
        /// <returns></returns>
        IUpdateSqlBuilder Where<TClass>(Expression<Func<TClass, bool>> where, bool isAnd = true) where TClass : class, new();
        //---------------------------------------------------------------------------------------------------------------
        /// <summary>
        /// 保存数据（自动新增或更新动作）,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entity">实体对象</param>
        /// <param name="where">条件表达式</param>
        /// <param name="columns">需要更新的字段</param>
        bool UpdateOrInsert<TClass>(TClass entity, Expression<Func<TClass, bool>> where, params string[] columns) where TClass : class, new();

        /// <summary>
        /// 保存数据多条数据（自动新增或更新动作）,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entities">数据列表</param>
        /// <param name="columns">需要更新的字段</param>
        bool UpdateOrInsert<TClass>(List<TClass> entities, params string[] columns) where TClass : class, new();

        /// <summary>
        /// 保存数据（自动新增或更新动作）,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entity">实体对象</param>
        /// <param name="where">条件表达式</param>
        /// <param name="IgnoreColumns">不需要更新的字段</param>
        bool UpdateOrInsert<TClass>(TClass entity, Expression<Func<TClass, bool>> where, IEnumerable<string> IgnoreColumns) where TClass : class, new();

        /// <summary>
        /// 保存数据多条数据（自动新增或更新动作）,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entities">数据列表</param>
        /// <param name="IgnoreColumns">不需要更新的字段</param>
        bool UpdateOrInsert<TClass>(List<TClass> entities, IEnumerable<string> IgnoreColumns = null) where TClass : class, new();

        /// <summary>
        /// 保存数据（自动新增或更新动作）
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="fields">设置多个更新字段</param>
        /// <param name="where">条件表达式</param>
        /// <returns></returns>
        bool UpdateOrInsert<TClass>(Expression<Func<TClass, TClass>> fields, Expression<Func<TClass, bool>> where) where TClass : class, new();

        //---------------------------------------------------------------------------------------------------------------
        /// <summary>
        /// 通过主键，判断实体是否存在表中
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        bool Exists<TClass>(TClass entity) where TClass : class, new();
        /// <summary>
        /// 通过主键，判断实体是否存在表中
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        bool Exists<TClass>(Expression<Func<TClass, bool>> where) where TClass : class, new();
    }
    #endregion
    #region IUpdateSqlBuilder<TClass>
    /// <summary>
    /// 单表操作
    /// </summary>
    /// <typeparam name="TClass"></typeparam>
    public partial interface IUpdateSqlBuilder<TClass> : IExecuteSql where TClass : class, new()
    {
        /// <summary>
        /// 更新一条数据,自动对比新老实体对象属性差异来决定更新字段
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="newEntity">新实体</param>
        /// <param name="oldEntity">老实体</param>
        /// <returns></returns>
        bool Update(TClass newEntity, TClass oldEntity);

        /// <summary>
        /// 更新一条数据,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entity">实体对象</param>
        /// <param name="columns">需要更新的字段</param>
        bool Update(TClass entity, params string[] columns);

        /// <summary>
        /// 更新多条数据,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entities">数据列表</param>
        /// <param name="isForSet">控制fields</param>
        /// <param name="columns">需要更新的字段</param>
        bool Update(List<TClass> entities, params string[] columns);

        /// <summary>
        /// 更新多条数据,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entities">数据列表</param>
        /// <param name="IgnoreColumns">不需要更新的字段</param>
        bool Update(List<TClass> entities, IEnumerable<string> IgnoreColumns = null);

        /// <summary>
        /// 更新一条数据,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entity">实体对象</param>
        /// <param name="IgnoreColumns">不需要更新的字段</param>
        bool Update(TClass entity, IEnumerable<string> IgnoreColumns = null);
        //---------------------------------------------------------------------------------------------------------------
        /// <summary>
        /// 更新一条数据,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entity">实体对象</param>
        /// <param name="where">条件表达式</param>
        /// <param name="columns">需要更新的字段</param>
        bool Update(TClass entity, Expression<Func<TClass, bool>> where, params string[] columns);

        /// <summary>
        /// 更新多条数据,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entities">数据列表</param>
        /// <param name="where">条件表达式</param>
        /// <param name="columns">需要更新的字段</param>
        bool Update(List<TClass> entities, Expression<Func<TClass, bool>> where, params string[] columns);

        /// <summary>
        /// 更新多条数据,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entities">数据列表</param>
        /// <param name="where">条件表达式</param>
        /// <param name="IgnoreColumns">不需要更新的字段</param>
        bool Update(List<TClass> entities, Expression<Func<TClass, bool>> where, IEnumerable<string> IgnoreColumns = null);

        /// <summary>
        /// 更新一条数据,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entity">实体对象</param>
        /// <param name="where">条件表达式</param>
        /// <param name="IgnoreColumns">不需要更新的字段</param>
        bool Update(TClass entity, Expression<Func<TClass, bool>> where, IEnumerable<string> IgnoreColumns);

        /// <summary>
        /// 更新一条数据
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="fields">设置多个更新字段</param>
        /// <param name="where">条件表达式</param>
        /// <returns></returns>
        bool Update(Expression<Func<TClass, TClass>> fields, Expression<Func<TClass, bool>> where);

        /// <summary>
        /// 设置多个更新字段
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="field">需要更新的字段</param>
        /// <returns></returns>
        IUpdateSqlBuilder<TClass> Set(Expression<Func<TClass, TClass>> fields);
        /// <summary>
        /// 设置单个更新字段值
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <typeparam name="TField"></typeparam>
        /// <param name="field">更新字段</param>
        /// <param name="value">字段值</param>
        /// <returns></returns>
        IUpdateSqlBuilder<TClass> Set<TValue>(Expression<Func<TClass, TValue>> field, TValue value);

        /// <summary>
        /// 添加条件表达式
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="where"></param>
        /// <returns></returns>
        IUpdateSqlBuilder<TClass> Where(Expression<Func<TClass, bool>> where, bool isAnd = true);
        //---------------------------------------------------------------------------------------------------------------
        /// <summary>
        /// 保存数据（自动新增或更新动作）,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entity">实体对象</param>
        /// <param name="where">条件表达式</param>
        /// <param name="columns">需要更新的字段</param>
        bool UpdateOrInsert(TClass entity, Expression<Func<TClass, bool>> where, params string[] columns);

        /// <summary>
        /// 保存数据多条数据（自动新增或更新动作）,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entities">数据列表</param>
        /// <param name="columns">需要更新的字段</param>
        bool UpdateOrInsert(List<TClass> entities, params string[] columns);

        /// <summary>
        /// 保存数据（自动新增或更新动作）,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entity">实体对象</param>
        /// <param name="where">条件表达式</param>
        /// <param name="IgnoreColumns">不需要更新的字段</param>
        bool UpdateOrInsert(TClass entity, Expression<Func<TClass, bool>> where, IEnumerable<string> IgnoreColumns);

        /// <summary>
        /// 保存数据多条数据（自动新增或更新动作）,某些属性,默认更新实体列表，所有字段
        /// </summary>
        /// <typeparam name="TClass">实体类型</typeparam>
        /// <param name="entities">数据列表</param>
        /// <param name="IgnoreColumns">不需要更新的字段</param>
        bool UpdateOrInsert(List<TClass> entities, IEnumerable<string> IgnoreColumns = null);

        /// <summary>
        /// 保存数据（自动新增或更新动作）
        /// </summary>
        /// <typeparam name="TClass"></typeparam>
        /// <param name="fields">设置多个更新字段</param>
        /// <param name="where">条件表达式</param>
        /// <returns></returns>
        bool UpdateOrInsert(Expression<Func<TClass,TClass>> fields, Expression<Func<TClass, bool>> where);

        //---------------------------------------------------------------------------------------------------------------
        /// <summary>
        /// 通过主键，判断实体是否存在表中
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        bool Exists(TClass entity);
        /// <summary>
        /// 通过主键，判断实体是否存在表中
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        bool Exists(Expression<Func<TClass, bool>> where);
    }
    #endregion
}
